use super::entry::{Entry, PATH_LIST_SAPARATOR, self};
use std::fmt;

pub struct CompositeEntry {
    entrys: Vec<Box<dyn Entry>>
}

impl CompositeEntry {
    pub fn new(path_list: &str) -> CompositeEntry {
        let paths = path_list.split(PATH_LIST_SAPARATOR);
        let entrys: Vec<Box<dyn Entry>> = paths.map(|path| entry::new_entry(path)).collect();
        CompositeEntry { entrys }
    }

    pub fn from(entrys: Vec<Box<dyn Entry>>) -> CompositeEntry {
        CompositeEntry { entrys }
    }
}

impl Entry for CompositeEntry {
    fn read_class(&self, class_name: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
        // 便利所有路径查找class_name
        for entry in &self.entrys {
            let res = entry.read_class(class_name);
            // 找到直接返回
            if let Ok(data) = res {
                return Ok(data);
            }
        }
        // 没有找到返回错误信息
        let err_msg = "class not found: ".to_string() + class_name;
        Err(err_msg.into())
    }

    fn string(&self) -> String {
        let str: Vec<String> = self.entrys.iter().map(|entry| entry.string()).collect();
        // 使用路径分隔符拼接所有路径
        str.join(PATH_LIST_SAPARATOR.to_string().as_str())
    }
}


impl fmt::Display for CompositeEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let string:Vec<String> = self.entrys.iter().map(|entry| entry.string()).collect();
        write!(f, "{}", string.join(PATH_LIST_SAPARATOR.to_string().as_str()))
    }
}